home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / sun / rlelib / rle_getraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-15  |  7.4 KB  |  292 lines

  1. /*
  2.  * This software is copyrighted as noted below.  It may be freely copied,
  3.  * modified, and redistributed, provided that the copyright notice is 
  4.  * preserved on all copies.
  5.  * 
  6.  * There is no warranty or other guarantee of fitness for this software,
  7.  * it is provided solely "as is".  Bug reports or fixes may be sent
  8.  * to the author, who may or may not act on them as he desires.
  9.  *
  10.  * You may not include this software in a program or other software product
  11.  * without supplying the source, or without informing the end-user that the 
  12.  * source is available for no extra charge.
  13.  *
  14.  * If you modify this software, you should include a notice giving the
  15.  * name of the person performing the modification, the date of modification,
  16.  * and the reason for such modification.
  17.  *
  18.  *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
  19.  *  to have all "void" functions so declared.
  20.  */
  21. /* 
  22.  * rle_getraw.c - 
  23.  * 
  24.  * Author:    Spencer W. Thomas
  25.  *         Computer Science Dept.
  26.  *         University of Utah
  27.  * Date:    Mon Nov 10 1986
  28.  * Copyright (c) 1986, University of Utah
  29.  */
  30. #ifndef lint
  31. static char rcs_ident[] = "$Id: rle_getraw.c,v 3.0 90/08/03 15:20:41 spencer Exp $";
  32. #endif
  33.  
  34. #include <stdio.h>
  35. #include <rle.h>
  36. #include <rle_raw.h>
  37. #ifdef USE_STDLIB_H
  38. #include <stdlib.h>
  39. #else
  40.  
  41. #ifndef VOID_STAR
  42. extern char * malloc();
  43. #else
  44. extern void *malloc();
  45. #endif
  46. extern void free();
  47.  
  48. #endif /* USE_STDLIB_H */
  49.  
  50. /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
  51. #define VAXSHORT( var, fp )\
  52.     { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
  53.   
  54. /* Instruction format -- first byte is opcode, second is datum. */
  55.  
  56. #define OPCODE(inst) (inst[0] & ~LONG)
  57. #define LONGP(inst) (inst[0] & LONG)
  58. #define DATUM(inst) (inst[1] & 0xff)    /* Make sure it's unsigned. */
  59.  
  60. /*****************************************************************
  61.  * TAG( rle_getraw )
  62.  * 
  63.  * Get a raw scanline from the input file.
  64.  * Inputs:
  65.  *    the_hdr:    rle_hdr structure containing information about 
  66.  *            the input file.
  67.  * Outputs:
  68.  *     scanraw:    an array of pointers to the individual color
  69.  *            scanlines.  Scanraw is assumed to have
  70.  *            the_hdr->ncolors pointers to arrays of rle_op,
  71.  *            each of which with enough elements, at least
  72.  *            1 + (the_hdr->xmax - the_hdr->xmin) / 3.
  73.  *    nraw:        an array of integers giving the number of rle_ops for
  74.  *            each color channel.
  75.  *    Returns the current scanline number.  Returns 32768 at EOF.
  76.  * Assumptions:
  77.  *     rle_get_setup has already been called.
  78.  * Algorithm:
  79.  *    Read input until a vertical skip is encountered,
  80.  *    decoding the instructions into the scanraw array.
  81.  *    Vertical skips that separate scanlines with no data do not
  82.  *    cause a return.  In other words, the only reason for returning
  83.  *    with an empty scanline is end of file.
  84.  *
  85.  *    When the scan_y reaches or exceeds the ymax, the rest of the
  86.  *    input image is skipped.  This avoids problems with malformed
  87.  *    input files.
  88.  */
  89. unsigned int
  90. rle_getraw( the_hdr, scanraw, nraw )
  91. rle_hdr *the_hdr;
  92. rle_op *scanraw[];
  93. int nraw[];
  94. {
  95.     register int channel;
  96.     register rle_op * rawp = NULL;
  97.     FILE *infile = the_hdr->rle_file;
  98.     char inst[2];
  99.     int scan_x = the_hdr->xmin;
  100.     register int was_data;
  101.     short word, long_data, nc, been_some = 0;
  102.  
  103.     /* Add in vertical skip from last scanline */
  104.     if ( the_hdr->priv.get.vert_skip > 0 )
  105.     the_hdr->priv.get.scan_y += the_hdr->priv.get.vert_skip;
  106.  
  107.     /* Set run lengths to 0 */
  108.     for ( channel = (the_hdr->alpha ? -1 : 0);
  109.       channel < the_hdr->ncolors;
  110.       channel++ )
  111.     if ( RLE_BIT( *the_hdr, channel ) )
  112.          nraw[channel] = 0;
  113.     channel = 0;
  114.  
  115.     if ( the_hdr->priv.get.is_eof )
  116.     return 32768;        /* too big for 16 bits, signal EOF */
  117.  
  118.     /* Otherwise, read and interpret instructions until a skipLines
  119.      * instruction is encountered.
  120.      */
  121.     for (was_data = 0;;)
  122.     {
  123.         inst[0] = getc( infile );
  124.     inst[1] = getc( infile );
  125.     if ( feof(infile) )
  126.     {
  127.         the_hdr->priv.get.is_eof = 1;
  128.         break;        /* <--- one of the exits */
  129.     }
  130.  
  131.     switch( OPCODE(inst) )
  132.     {
  133.     case RSkipLinesOp:
  134.         was_data = 1;
  135.         if ( LONGP(inst) )
  136.         {
  137.         VAXSHORT( the_hdr->priv.get.vert_skip, infile );
  138.         }
  139.         else
  140.         the_hdr->priv.get.vert_skip = DATUM(inst);
  141.         break;            /* need to break for() here, too */
  142.  
  143.     case RSetColorOp:
  144.         was_data = 1;
  145.         channel = DATUM(inst);    /* select color channel */
  146.         if ( channel == 255 )
  147.         channel = -1;
  148.         scan_x = the_hdr->xmin;
  149.         if ( RLE_BIT( *the_hdr, channel ) )
  150.         rawp = scanraw[channel];
  151.         else
  152.         rawp = NULL;
  153.         break;
  154.  
  155.     case RSkipPixelsOp:
  156.         was_data = 1;
  157.         if ( LONGP(inst) )
  158.         {
  159.             VAXSHORT( long_data, infile );
  160.         scan_x += long_data;
  161.         }
  162.         else
  163.         {
  164.         scan_x += DATUM(inst);
  165.         }
  166.         break;
  167.  
  168.     case RByteDataOp:
  169.         was_data = 1;
  170.         if ( LONGP(inst) )
  171.         {
  172.             VAXSHORT( nc, infile );
  173.         }
  174.         else
  175.         nc = DATUM(inst);
  176.         nc++;
  177.         if ( rawp != NULL )
  178.         {
  179.         rawp->opcode = RByteDataOp;
  180.         rawp->xloc = scan_x;
  181.         rawp->length = nc;
  182.         rawp->u.pixels = (rle_pixel *)malloc( (unsigned)nc );
  183.         fread( (char *)rawp->u.pixels, 1, nc, infile );
  184.         if ( nc & 1 )
  185.             (void)getc( infile );    /* throw away odd byte */
  186.         rawp++;
  187.         nraw[channel]++;
  188.         }
  189.         else
  190.         if ( the_hdr->priv.get.is_seek )
  191.             fseek( infile, ((nc + 1) / 2) * 2, 1 );
  192.         else
  193.         {
  194.             register int ii;
  195.             for ( ii = ((nc + 1) / 2) * 2; ii > 0; ii-- )
  196.             (void) getc( infile );    /* discard it */
  197.         }
  198.  
  199.         scan_x += nc;
  200.         been_some = 1;
  201.         break;
  202.  
  203.     case RRunDataOp:
  204.         was_data = 1;
  205.         if ( LONGP(inst) )
  206.         {
  207.             VAXSHORT( nc, infile );
  208.         }
  209.         else
  210.         nc = DATUM(inst);
  211.  
  212.         nc++;
  213.         VAXSHORT( word, infile );
  214.         if ( rawp != NULL )
  215.         {
  216.         rawp->opcode = RRunDataOp;
  217.         rawp->xloc = scan_x;
  218.         rawp->length = nc;
  219.         rawp->u.run_val = word;
  220.         rawp++;
  221.         nraw[channel]++;
  222.         }
  223.         scan_x += nc;
  224.         been_some = 1;
  225.         break;
  226.  
  227.     case REOFOp:
  228.         the_hdr->priv.get.is_eof = 1;
  229.         break;
  230.  
  231.     default:
  232.         fprintf( stderr, "rle_getraw: Unrecognized opcode: %d\n", OPCODE(inst) );
  233.         exit(1);
  234.     }
  235.     if ( OPCODE(inst) == REOFOp )
  236.         break;            /* <--- the other loop exit */
  237.     if ( OPCODE(inst) == RSkipLinesOp )
  238.     {
  239.         if ( been_some )
  240.         break;            /* <--- the other loop exit */
  241.         else
  242.         /* No data on that scanline, so move up to this scanline */
  243.         the_hdr->priv.get.scan_y +=
  244.             the_hdr->priv.get.vert_skip;
  245.     }
  246.     }
  247.  
  248.     /* If at top of image, skip any remaining. */
  249.     if ( the_hdr->priv.get.scan_y >= the_hdr->ymax )
  250.     {
  251.     int y = the_hdr->priv.get.scan_y;
  252.     while ( rle_getskip( the_hdr ) != 32768 )
  253.         ;
  254.     return y;
  255.     }
  256.  
  257.     /* Return current Y value */
  258.     return (was_data == 0) ? 32768 : the_hdr->priv.get.scan_y;
  259. }
  260.  
  261. /*****************************************************************
  262.  * TAG( rle_freeraw )
  263.  * 
  264.  * Free all the pixel arrays in the raw scan struct.
  265.  * Inputs:
  266.  *      the_hdr:    Header struct corresponding to this RLE data.
  267.  *      scanraw:    Array of pointers to array of rle_op, as above.
  268.  *     nraw:        Array of lengths (as above)
  269.  * Outputs:
  270.  *     Frees the areas pointed to by the pixels elements of any
  271.  *      RByteDataOp type rle_op structs.
  272.  * Assumptions:
  273.  *    [None]
  274.  * Algorithm:
  275.  *    [None]
  276.  */
  277. void
  278. rle_freeraw( the_hdr, scanraw, nraw )
  279. rle_hdr * the_hdr;
  280. int nraw[];
  281. rle_op *scanraw[] ;
  282. {
  283.     int c, i;
  284.     register rle_op * raw_p;
  285.  
  286.     for ( c = -the_hdr->alpha; c < the_hdr->ncolors; c++ )
  287.     if ( RLE_BIT( *the_hdr, c ) )
  288.         for ( i = nraw[c], raw_p = scanraw[c]; i > 0; i--, raw_p++ )
  289.         if ( raw_p->opcode == RByteDataOp )
  290.             free( raw_p->u.pixels );
  291. }
  292.